﻿using System;
using System.Collections.Generic;
using Swirebev.PhotoDownload.Model;
using Swirebev.PhotoDownload.Common;
using System.Reflection;
using System.Net;
using System.Web;
using Newtonsoft.Json.Linq;
using System.IO;
using System.Drawing;
using Swirebev.PhotoDownload.DAL;
using System.Drawing.Imaging;


namespace Swirebev.PhotoDownload.Cloud
{
	public class AVOSCloudHelper
	{
		private const string CloudTableName_File = "_File";

		private static AVOSCloudHelper _instance;
		public static AVOSCloudHelper Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new AVOSCloudHelper();
				}
				return _instance;
			}
		}

		public List<PhotoData> DownloadPhotos()
		{
            string objectId = "";
			try
			{
                //Proxy.ProxyUrl = Settings.Instance.ProxyUrl;
                //Proxy.ProxyUserName = Settings.Instance.ProxyUserName;
                //Proxy.ProxyPassword = Settings.Instance.ProxyPassword;

                AVOSHelper avosHelp = new AVOSHelper(Settings.Instance.ApplicationId,
				Settings.Instance.AppKey, "https://leancloud.cn/1");

				avosHelp.IsProxy = false;

				string jsonWhere = @"{}";
				jsonWhere = HttpUtility.UrlEncode(jsonWhere);
				JObject jo = avosHelp.QueryAVClasses(CloudTableName_File, jsonWhere, Settings.Instance.DownloadPhotoQuantityOnce, "-updatedAt");

				List<PhotoData> photoList = new List<PhotoData>();
				if (jo != null && jo["results"].ToString() != "[]")
				{
					JArray jArr = (JArray)jo["results"];

					foreach (JObject jobj in jArr)
					{
						PhotoData photoData = new PhotoData();
						photoData.DownloadStatus = PhotoDownloadStatus.DownloadFail_NetworkError;
						photoData.PhotoBuffer = null;
						//string objectId = "";
						objectId = jobj["objectId"].ToString();
						photoData.ObjectId = objectId;
						string shortName = "";
						shortName = jobj["name"].ToString().Replace("|", "_");

                        shortName = shortName.ToString().Replace("%7C", "_");
                        shortName = shortName.ToString().Replace("%7c", "_");
						photoData.BusinessId = (shortName.Split('_'))[1];//业务编号
						string businessTypeCd = (shortName.Split('_'))[3];//业务类型代码 420003:客户门招图片；420001:活动检查图片
                        photoData.BusinessTypeCd = businessTypeCd;
                        if (businessTypeCd == "420021")
                            photoData.BusinessTypeCd = "420001";
                        else if (businessTypeCd == "420020")
                            photoData.BusinessTypeCd = "420003";

						photoData.StoreId = (shortName.Split('_'))[0];//客户编号
						photoData.RouteId = (shortName.Split('_'))[2];//线路编号

                        string createAt = jobj["createdAt"].ToString();
                        //if (createAt != null || createAt != "")
                        //    photoData.CreateAt = createAt;
                        //else
                        //    photoData.CreateAt = DateTime.Now.ToString();

                        string mimeType = jobj["mime_type"].ToString();
                        string exName = (mimeType.Split('/'))[1];

						string strUrl = string.Empty;
						strUrl = jobj["url"].ToString();

                        if (strUrl.Contains("data:image/png;base64,") || strUrl.Contains("data:image/jpeg;base64,"))
                        {
                            strUrl = strUrl.Replace(@"data:image/png;base64,", "");
                            strUrl = strUrl.Replace(@"data:image/jpeg;base64,", "");
                            photoData.PhotoURL = strUrl.Trim();

                            byte[] imageBytes = Convert.FromBase64String(strUrl);

                            using (MemoryStream memoryStream = new MemoryStream(imageBytes, 0, imageBytes.Length))//读入MemoryStream对象
                            {
                                memoryStream.Write(imageBytes, 0, imageBytes.Length);

                                using (System.Drawing.Image image = System.Drawing.Image.FromStream(memoryStream))//转成图片
                                {
                                    string fullName = "";
                                    fullName = objectId + "." + exName;
                                    photoData.PhotoName = fullName;
                                    if (photoData.BusinessTypeCd == "420001")
                                    {
                                        photoData.DisplayName = photoData.StoreId + "_01." + exName;
                                    }
                                    else
                                    {
                                        photoData.DisplayName = photoData.StoreId + "_03." + exName;
                                    }

                                    if (!File.Exists(Settings.Instance.photoSaveAllPath + fullName))
                                    {
                                        image.Save(Settings.Instance.photoSaveAllPath + fullName);
                                    }
                                    photoList.Add(photoData);
                                    objectId = "";
                                }
                            }
                        }
                        else 
                        {
                            string fullName = "";
                            fullName = objectId + "." + exName;
                            photoData.PhotoName = fullName;
                            if (photoData.BusinessTypeCd == "420001")
                            {
                                photoData.DisplayName = photoData.StoreId + "_01." + exName;
                            }
                            else
                            {
                                photoData.DisplayName = photoData.StoreId + "_03." + exName;
                            }

                            photoData.PhotoURL = strUrl.Trim();

                            bool value = false;
                            WebResponse response = null;
                            Stream stream = null;
                            try
                            {
                                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(strUrl);
                                System.Net.WebProxy proxy = new WebProxy(Settings.Instance.ProxyUrl, Convert.ToInt32(Settings.Instance.ProxyPort));
                                proxy.Credentials = new NetworkCredential(Settings.Instance.ProxyUserName, Settings.Instance.ProxyPassword);
                                request.Proxy = proxy; 
                                response = request.GetResponse();
                                stream = response.GetResponseStream();

                                if (!response.ContentType.ToLower().StartsWith("text/"))
                                {
                                    //value = SaveBinaryFile(response, Settings.Instance.photoSaveAllPath + fullName);
                                    //创建一个图像对象取得上传图片对象
                                    System.Drawing.Image image = System.Drawing.Image.FromStream(stream, false);
                                    //int width = Convert.ToInt32(Settings.Instance.imageWidth);
                                    //int height = Convert.ToInt32(Settings.Instance.imageHeight);

                                    int width = Convert.ToInt32(image.Width);  
                                    int height = Convert.ToInt32(image.Height); 

                                    //System.Drawing.Bitmap img = new System.Drawing.Bitmap(image);
                                    //int imgHeight = Convert.ToInt32(img.Size.Height);
                                    //int imgWidth = Convert.ToInt32(img.Size.Width);

                                    if (width > height)
                                    {
                                        width = 480; height = 350;

                                    }
                                    else
                                    {
                                        width = 350; height = 480;
                                    }

                                    System.Drawing.Bitmap saveImage = new System.Drawing.Bitmap(image, width, height);//图片保存的大小尺寸  
                                    saveImage.Save(Settings.Instance.photoSaveAllPath + fullName, ImageFormat.Jpeg);
                                }
                                photoList.Add(photoData);
                                objectId = "";
                            }
                            catch (Exception ex)
                            {
                                Log.Error(MethodBase.GetCurrentMethod().DeclaringType, "Download:" + fullName + "failed", ex);
                            }
                            finally
                            {
                                if (stream != null) stream.Close();
                                if (response != null) response.Close();
                            }
                        }
					}
					Log.Info(MethodBase.GetCurrentMethod().DeclaringType, "Download [" + photoList.Count + "] photos");
				}
				else
				{
					Log.Info(MethodBase.GetCurrentMethod().DeclaringType, "Failed to download photos,Try again next time");
				}
				return photoList;
			}
			catch (Exception ex)
			{
				Log.Error(MethodBase.GetCurrentMethod().DeclaringType, "Failed to get photolist from leancloud"+objectId, ex);
                if (UpdateDownloadSuccess(objectId))
                    Log.Info(MethodBase.GetCurrentMethod().DeclaringType, "Exception delete the photo" + objectId);
                else
                    Log.Info(MethodBase.GetCurrentMethod().DeclaringType, "Exception failed to delete the photo" + objectId);
				return null;
			}
		}

        private static bool SaveBinaryFile(WebResponse response, string savePath)
        {
            bool value = false;
            byte[] buffer = new byte[2048];//TODO 2048 需要修改大小
            Stream outStream = null;
            Stream inStream = null;
            try
            {
                if (File.Exists(savePath)) 
                    File.Delete(savePath);
                outStream = System.IO.File.Create(savePath);
                inStream = response.GetResponseStream();
                int l;
                do
                {
                    l = inStream.Read(buffer, 0, buffer.Length);
                    if (l > 0) outStream.Write(buffer, 0, l);
                } while (l > 0);
                value = true;
            }
            finally
            {
                if (outStream != null) outStream.Close();
                if (inStream != null) inStream.Close();
            }
                return value;
        }

		public void SavePhoto(PhotoData photoData)
		{
			try
			{
				string saleCenterName = "";
				string _strSpliter = "\\";
				string _strPhototypename = "";
				saleCenterName = photoData.RouteId == null ? string.Empty : GetSalesCenterByRoute(photoData.RouteId);
				string prjectstoreDirectory = saleCenterName + _strSpliter +
						photoData.RouteId + _strSpliter;

				if (photoData.BusinessTypeCd == "420003")
				{
					_strPhototypename = "活动";
					prjectstoreDirectory = prjectstoreDirectory + _strPhototypename + _strSpliter;
				}
				else if (photoData.BusinessTypeCd == "420001")
				{
					_strPhototypename = "门招";
					prjectstoreDirectory = prjectstoreDirectory + _strPhototypename + _strSpliter;
				}
				byte[] imageBytes = Convert.FromBase64String(photoData.PhotoURL);
				MemoryStream memoryStream = new MemoryStream(imageBytes, 0, imageBytes.Length);
				memoryStream.Write(imageBytes, 0, imageBytes.Length);
				Image image = Image.FromStream(memoryStream);
				CreateDirectory(Settings.Instance.photoSaveAllPath + prjectstoreDirectory);
				image.Save(Settings.Instance.photoSaveAllPath + prjectstoreDirectory + photoData.PhotoName); 
				Log.Info(MethodBase.GetCurrentMethod().DeclaringType, "success to save outletPhotos");
			}
			catch (Exception ex)
			{
				Log.Error(MethodBase.GetCurrentMethod().DeclaringType, "failed to save outletPhotos", ex);
			}
		}

		/// <summary>
		/// 取营业所名称
		/// </summary>
		/// <param name="routeId"></param>
		/// <returns></returns>
		public static string GetSalesCenterByRoute(string routeId)
		{
			return LocationDataAccess.GetSalesCenterByRoute(routeId);
		}

		/// <summary>
		/// 创建文件夹
		/// </summary>
		/// <param name="directoryName"></param>
		private static void CreateDirectory(string directoryName)
		{
			if (!Directory.Exists(directoryName))
			{
				Directory.CreateDirectory(directoryName);
			}
		}

        public bool UpdateDownloadSuccess(string objectId)
		{
			try
			{
				AVOSHelper avosHelp = new AVOSHelper(Settings.Instance.ApplicationId,
				Settings.Instance.AppKey, "https://leancloud.cn/1");

				avosHelp.IsProxy = true;
                if (avosHelp.DeleteAVClass(CloudTableName_File, objectId))
				{
                    Log.Info(MethodBase.GetCurrentMethod().DeclaringType, "Success to delete the photo,objectId:[" + objectId + "]");
				}
				else
				{
                    Log.Info(MethodBase.GetCurrentMethod().DeclaringType, "Failed to delete the photo,objectId:[" + objectId + "]");
				}
				return true;
			}
			catch (Exception ex)
			{
                Log.Error(MethodBase.GetCurrentMethod().DeclaringType, "Failed to download flag,objectId:[" + objectId + "]", ex);
				return false;
			}
		}

	}
}
